import { AppDataSource } from '../../data-source'
import { Request, Response } from 'express'
import { Random } from '../../utils/random-utils'
import { responseHandler, errorHandler, paramsHandler } from '../../utils/handler-utils'
import { videoProjectDir, deleteFolder, moveFile } from "../../utils/storage-utils";
import { videoProjectEntity } from '../../entity/videoProject_entity'
import { NodeEntity } from '../../entity/node_entity'
import { VideoEntity } from '../../entity/video_entity'
import { pathToURL, urlToPath } from "../../utils/address-utils";
import * as path from "path"
import * as fs from 'fs';
import type {
    CreateNodeVideoProjectRequestBody,
    EditProjectCoverRequestBody,
    DeleteNodeVideoProjectRequestBody,
} from "./types";

const random = new Random()
const projectRepository = AppDataSource.getRepository(videoProjectEntity)
const nodeRepository = AppDataSource.getRepository(NodeEntity)
const videoRepository = AppDataSource.getRepository(VideoEntity)

class Basic {

    /**
     * 创建项目
     * @returns 
     */
    createProject = async (req: Request, res: Response) => {
        if (!req.file) {
            responseHandler({
                httpStatus: 400,
                code: 1,
                message: "未检测到上传文件",
                req,
                res,
            });
            return;
        }
        try {
            // 首先声明一个注册 消息的结构体
            var createBody = req.body as CreateNodeVideoProjectRequestBody;
            if (createBody.name == undefined) {
                // 参数错误
                paramsHandler(req.body, req, res)
                return
            }

            let projectId = random.randomString();
            var nodeVideoProjectDir = path.join(videoProjectDir, projectId); // 指定上传目录
            if (!fs.existsSync(nodeVideoProjectDir)) {
                fs.mkdirSync(nodeVideoProjectDir);
            }
            // 将封面图 移到项目目录
            var targetPath = path.join(videoProjectDir, projectId, req.file.filename);
            await moveFile(req.file.path, targetPath);

            let projectEntity = new videoProjectEntity()
            projectEntity.id = projectId;
            projectEntity.name = createBody.name;
            projectEntity.cover = pathToURL(targetPath);
            projectEntity.startId = '';

            await projectRepository.save(projectEntity)

            responseHandler({
                req,
                res,
                code: 0,
                data: projectEntity,
                message: "创建成功",
            })
        }
        catch (error) {
            errorHandler({
                error,
                message: "创建失败",
                data: { error },
                req,
                res,
            })
        }
    }

    /**
     * 删除项目
     * @returns 
     */
    deleteProject = async (req: Request, res: Response) => {
        try {
            // 首先声明一个注册 消息的结构体
            var deleteBody = req.body as DeleteNodeVideoProjectRequestBody;
            if (deleteBody.projectId == undefined) {
                // 参数错误
                paramsHandler(deleteBody, req, res)
                return
            }

            var projectDir = path.join(videoProjectDir, deleteBody.projectId);
            // 查询数据库实体
            let projectEntity = await projectRepository.findOneBy({ id: deleteBody.projectId });
            if (projectEntity == null) {
                responseHandler({
                    req,
                    res,
                    code: 0,
                    data: {
                        msg: "数据不存在,或者已经删除"
                    },
                    message: "删除成功",
                })
                // 删除文件目录
                deleteFolder(projectDir);
                return;
            } else {

                // 删除 节点列表
                let nodeList: NodeEntity[] = await nodeRepository.find({ where: { projectId: projectEntity.id } });
                for (let index = 0; index < nodeList.length; index++) {
                    const element = nodeList[index];
                    await nodeRepository.remove(element)
                }
                // 删除 视频列表
                let videoList: VideoEntity[] = await videoRepository.find({ where: { projectId: projectEntity.id } });
                for (let index = 0; index < videoList.length; index++) {
                    const element = videoList[index];
                    await videoRepository.remove(element)
                }

                // 删除文件目录
                deleteFolder(projectDir);

                // 删除数据库存储
                await projectRepository.remove(projectEntity)

                responseHandler({
                    req,
                    res,
                    code: 0,
                    data: null,
                    message: "删除成功",
                })
            }
        }
        catch (error) {
            errorHandler({
                error,
                message: "删除失败",
                data: { error },
                req,
                res,
            })
        }
    }

    /**
     * 获取项目列表
     * @returns 
     */
    getProjectList = async (req: Request, res: Response) => {
        try {

            let projectList: videoProjectEntity[] = await projectRepository.find();

            responseHandler({
                req,
                res,
                code: 0,
                data: projectList,
                message: "获取成功",
            })
        }
        catch (error) {
            errorHandler({
                error,
                message: "获取失败",
                data: { error },
                req,
                res,
            })
        }
    }

    /**
     * 获取项目详情
     * @returns 
     */
    getProjectDetails = async (req: Request, res: Response) => {
        try {
            const { projectId } = req.query;
            if (projectId == undefined) {
                // 参数错误
                paramsHandler(req.query, req, res)
                return
            }

            let projectEntity = await projectRepository.findOne({ where: { id: projectId as String } });

            if (projectEntity == null) {
                responseHandler({
                    req,
                    res,
                    code: 1,
                    data: {
                        "error": "未找到交互视频 id : " + projectId
                    },
                    message: "获取失败",
                })
                return
            }

            let nodeList: NodeEntity[] = await nodeRepository.find({ where: { projectId: projectId as String } });
            let videoList: VideoEntity[] = await videoRepository.find({ where: { projectId: projectId as String } });

            responseHandler({
                req,
                res,
                code: 0,
                data: {
                    "project": projectEntity,
                    "nodes": nodeList,
                    "videos": videoList,
                },
                message: "获取成功",
            })
        }
        catch (error) {
            errorHandler({
                error,
                message: "获取失败",
                data: { error },
                req,
                res,
            })
        }
    }

    /**
     * 编辑项目封面
     * @returns 
     */
    editProjectCover = async (req: Request, res: Response) => {
        try {
            // 首先声明一个注册 消息的结构体
            var editorBody = req.body as EditProjectCoverRequestBody;
            if (editorBody.projectId == undefined) {
                // 参数错误
                paramsHandler(editorBody, req, res)
                return
            }
            let projectEntity = await projectRepository.findOneBy({ id: editorBody.projectId });

            if (projectEntity == null) {
                responseHandler({
                    req,
                    res,
                    code: 1,
                    data: {
                        "error": "未找到交互视频 id : " + editorBody.projectId
                    },
                    message: "编辑失败",
                })
                return;
            }

            if (editorBody.projectName != undefined) {
                projectEntity.name = editorBody.projectName
            }

            if (req.file) {
                // 将封面图 移到项目目录
                var targetPath = path.join(videoProjectDir, editorBody.projectId, req.file.filename);
                await moveFile(req.file.path, targetPath);
                projectEntity.cover = pathToURL(targetPath)
            }

            await projectRepository.save(projectEntity)

            responseHandler({
                req,
                res,
                code: 0,
                data: projectEntity,
                message: "编辑成功",
            })
        }
        catch (error) {
            errorHandler({
                error,
                message: "编辑失败",
                data: { error },
                req,
                res,
            })
        }
    }

    /**
    * 编辑项目详情
    * @returns 
    */
    editProjectDetails = async (req: Request, res: Response) => {
        try {
            // 首先声明一个注册 消息的结构体
            var editorBody = req.body as EditProjectCoverRequestBody;
            if (editorBody.projectId == undefined) {
                // 参数错误
                paramsHandler(editorBody, req, res)
                return
            }

            let classEntity = await projectRepository.findOneBy({ id: editorBody.projectId });

            if (classEntity == null) {
                responseHandler({
                    req,
                    res,
                    code: 1,
                    data: {
                        "error": "未找到交互视频 id : " + editorBody.projectId
                    },
                    message: "编辑失败",
                })
                return;
            }


            responseHandler({
                req,
                res,
                code: 0,
                data: classEntity,
                // message: "编辑成功",
                message: "接口暂时没有开发",
            })
        }
        catch (error) {
            errorHandler({
                error,
                message: "编辑失败",
                data: { error },
                req,
                res,
            })
        }
    }
}

export const basic = new Basic();